/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : usbd_custom_hid_if.c
  * @version        : v2.0_Cube
  * @brief          : USB Device Custom HID interface file.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "usbd_custom_hid_if.h"

/* USER CODE BEGIN INCLUDE */

/* USER CODE END INCLUDE */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/

/* USER CODE END PV */

/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
  * @brief Usb device.
  * @{
  */

/** @addtogroup USBD_CUSTOM_HID
  * @{
  */

/** @defgroup USBD_CUSTOM_HID_Private_TypesDefinitions USBD_CUSTOM_HID_Private_TypesDefinitions
  * @brief Private types.
  * @{
  */

/* USER CODE BEGIN PRIVATE_TYPES */

/* USER CODE END PRIVATE_TYPES */

/**
  * @}
  */

/** @defgroup USBD_CUSTOM_HID_Private_Defines USBD_CUSTOM_HID_Private_Defines
  * @brief Private defines.
  * @{
  */

/* USER CODE BEGIN PRIVATE_DEFINES */

/* USER CODE END PRIVATE_DEFINES */

/**
  * @}
  */

/** @defgroup USBD_CUSTOM_HID_Private_Macros USBD_CUSTOM_HID_Private_Macros
  * @brief Private macros.
  * @{
  */

/* USER CODE BEGIN PRIVATE_MACRO */

/* USER CODE END PRIVATE_MACRO */

/**
  * @}
  */

/** @defgroup USBD_CUSTOM_HID_Private_Variables USBD_CUSTOM_HID_Private_Variables
  * @brief Private variables.
  * @{
  */

/** Usb HID report descriptor. */
__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
  /* USER CODE BEGIN 0 */
		0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
		0x09, 0x06,        // Usage (Keyboard)
		0xA1, 0x01,        // Collection (Application)
		0x85, 0x01,        //   Report ID (1)
		0x05, 0x07,        //   Usage Page (Kbrd/Keypad)
		0x19, 0xE0,        //   Usage Minimum (0xE0)
		0x29, 0xE7,        //   Usage Maximum (0xE7)
		0x15, 0x00,        //   Logical Minimum (0)
		0x25, 0x01,        //   Logical Maximum (1)
		0x75, 0x01,        //   Report Size (1)
		0x95, 0x08,        //   Report Count (8)
		0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
		0x75, 0x08,        //   Report Size (8)
		0x95, 0x01,        //   Report Count (1)
		0x81, 0x01,        //   Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
		0x75, 0x08,        //   Report Size (8)
		0x95, 0x06,        //   Report Count (6)
		0x15, 0x00,        //   Logical Minimum (0)
		0x25, 0x65,        //   Logical Maximum (101)
		0x05, 0x07,        //   Usage Page (Kbrd/Keypad)
		0x19, 0x00,        //   Usage Minimum (0x00)
		0x29, 0x65,        //   Usage Maximum (0x65)
		0x81, 0x00,        //   Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
		0xC0,              // End Collection
		//key 47 bytes

		0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
		0x09, 0x02,        // Usage (Mouse)
		0xA1, 0x01,        // Collection (Application)
		0x85, 0x02,        //   Report ID (2)
		0x09, 0x01,        //   Usage (Pointer)
		0xA1, 0x00,        //   Collection (Physical)
		0x05, 0x09,        //     Usage Page (Button)
		0x19, 0x01,        //     Usage Minimum (0x01)
		0x29, 0x03,        //     Usage Maximum (0x03)
		0x15, 0x00,        //     Logical Minimum (0)
		0x25, 0x01,        //     Logical Maximum (1)
		0x75, 0x01,        //     Report Size (1)
		0x95, 0x03,        //     Report Count (3)
		0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
		0x75, 0x01,        //     Report Size (1)
		0x95, 0x05,        //     Report Count (5)
		0x81, 0x01,        //     Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
		0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
		0x09, 0x30,        //     Usage (X)
		0x09, 0x31,        //     Usage (Y)
		0x15, 0x81,        //     Logical Minimum (-127)
		0x25, 0x7F,        //     Logical Maximum (127)
		0x75, 0x08,        //     Report Size (8)
		0x95, 0x02,        //     Report Count (2)
		0x81, 0x06,        //     Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
		0xC0,              //   End Collection
		0xC0,              //   End Collection
		// 52 bytes
		//=== 简化多媒体控制报告 (Report ID 3) ===//
		0x05, 0x0C,        // USAGE_PAGE (Consumer)
		0x09, 0x01,        // USAGE (Consumer Control)
		0xA1, 0x01,        // COLLECTION (Application)
		0x85, 0x03,        //   REPORT_ID (3)

		// 8位的控制字段（最常用的8个功能）
		0x15, 0x00,        //   LOGICAL_MINIMUM (0)
		0x25, 0x01,        //   LOGICAL_MAXIMUM (1)
		0x75, 0x01,        //   REPORT_SIZE (1)
		0x95, 0x08,        //   REPORT_COUNT (8)

		// 定义8个多媒体控制用途
		0x09, 0xCD,        //   USAGE (Play/Pause)
		0x09, 0xB5,        //   USAGE (Scan Next Track)
		0x09, 0xB6,        //   USAGE (Scan Previous Track)
		0x09, 0xE2,        //   USAGE (Mute)
		0x09, 0xE9,        //   USAGE (Volume Increment)
		0x09, 0xEA,        //   USAGE (Volume Decrement)
		0x09, 0xB7,        //   USAGE (Stop)
		0x09, 0x83,        //   USAGE (Media Select)

		0x81, 0x02,        //   INPUT (Data,Var,Abs)
//		0xC0               // END_COLLECTION
         //key mul 35bytes
  /* USER CODE END 0 */
  0xC0    /*     END_COLLECTION	             */
};

/* USER CODE BEGIN PRIVATE_VARIABLES */

/* USER CODE END PRIVATE_VARIABLES */

/**
  * @}
  */

/** @defgroup USBD_CUSTOM_HID_Exported_Variables USBD_CUSTOM_HID_Exported_Variables
  * @brief Public variables.
  * @{
  */
extern USBD_HandleTypeDef hUsbDeviceFS;

/* USER CODE BEGIN EXPORTED_VARIABLES */

/* USER CODE END EXPORTED_VARIABLES */
/**
  * @}
  */

/** @defgroup USBD_CUSTOM_HID_Private_FunctionPrototypes USBD_CUSTOM_HID_Private_FunctionPrototypes
  * @brief Private functions declaration.
  * @{
  */

static int8_t CUSTOM_HID_Init_FS(void);
static int8_t CUSTOM_HID_DeInit_FS(void);
static int8_t CUSTOM_HID_OutEvent_FS(uint8_t event_idx, uint8_t state);

/**
  * @}
  */

USBD_CUSTOM_HID_ItfTypeDef USBD_CustomHID_fops_FS =
{
  CUSTOM_HID_ReportDesc_FS,
  CUSTOM_HID_Init_FS,
  CUSTOM_HID_DeInit_FS,
  CUSTOM_HID_OutEvent_FS
};

/** @defgroup USBD_CUSTOM_HID_Private_Functions USBD_CUSTOM_HID_Private_Functions
  * @brief Private functions.
  * @{
  */

/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Initializes the CUSTOM HID media low layer
  * @retval USBD_OK if all operations are OK else USBD_FAIL
  */
static int8_t CUSTOM_HID_Init_FS(void)
{
  /* USER CODE BEGIN 4 */
  return (USBD_OK);
  /* USER CODE END 4 */
}

/**
  * @brief  DeInitializes the CUSTOM HID media low layer
  * @retval USBD_OK if all operations are OK else USBD_FAIL
  */
static int8_t CUSTOM_HID_DeInit_FS(void)
{
  /* USER CODE BEGIN 5 */
  return (USBD_OK);
  /* USER CODE END 5 */
}

/**
  * @brief  Manage the CUSTOM HID class events
  * @param  event_idx: Event index
  * @param  state: Event state
  * @retval USBD_OK if all operations are OK else USBD_FAIL
  */
static int8_t CUSTOM_HID_OutEvent_FS(uint8_t event_idx, uint8_t state)
{
  /* USER CODE BEGIN 6 */
  return (USBD_OK);
  /* USER CODE END 6 */
}

/* USER CODE BEGIN 7 */
/**
  * @brief  Send the report to the Host
  * @param  report: The report to be sent
  * @param  len: The report length
  * @retval USBD_OK if all operations are OK else USBD_FAIL
  */
/*
static int8_t USBD_CUSTOM_HID_SendReport_FS(uint8_t *report, uint16_t len)
{
  return USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, report, len);
}
*/
/* USER CODE END 7 */

/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */
int8_t CUSTOM_HID_SendReport(uint8_t *report, uint16_t len)
{
  /* 检查USB是否已配置 */
  if (hUsbDeviceFS.dev_state != USBD_STATE_CONFIGURED)
  {
    return USBD_FAIL;
  }

  /* 检查报告长度是否有效 */
  if (report == NULL || len == 0)
  {
    return USBD_FAIL;
  }

  /* 调用底层发送函数 */
  return USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, report, len);
}
/**
  * @brief 发送键盘报告
  */
int8_t HID_SendKeyMulReport( uint8_t keycode)
{
  uint8_t report[2] ={3,0};
  report[1] =keycode;
  // 字节4-8: 其他按键（默认为0）
  CUSTOM_HID_SendReport(report, 2);
  HAL_Delay(10);
  //释放按键
  report[1]=0;
  return CUSTOM_HID_SendReport(report, 2);
}
int8_t HID_SendKeyboardReport(uint8_t modifier, uint8_t keycode)
{
  uint8_t report[9] ={1};// 报告ID = 1
  report[0] =1;            //ID
  report[1] = modifier;    // 字节1: 修饰键
  report[2] = 0;           // 字节2: 保留
  report[3] = keycode;     // 字节3: 按键代码
  // 字节4-8: 其他按键（默认为0）
  CUSTOM_HID_SendReport(report, 9);
  HAL_Delay(10);
  //释放按键
//  report[0]=1;
  report[1]=0;
  report[3]=0;
  return CUSTOM_HID_SendReport(report, 9);
}
// 发送鼠标报告 (5字节: ID + 4字节数据)
int8_t HID_SendMouseReport(uint8_t buttons, int8_t x, int8_t y)
{
  uint8_t report[5] = {0x02}; // 报告ID = 2
  report[1] = buttons;        // 按钮状态
  //    0x01：左键按下。
  //    0x02：右键按下。
  //    0x04：中键按下。
  //    0x03：左键和右键同时按下
  report[2] = x;              // X位移
  report[3] = y;              // Y位移
  report[4] = 0;              // 滚轮(可选)
  USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, report,5);
  HAL_Delay(100);
  report[1] = 0;
  report[2] = 0;
  report[3] = 0;
  report[4] = 0;
  return USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, report, 5);
}
/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */
/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */

